import os
from re import template
import time
import logging

from django.shortcuts import render, HttpResponse
from django.utils.translation import gettext as _
from django.http import Http404, FileResponse
from django.views import generic
from django.utils.encoding import escape_uri_path

from django.db.models import Q

from .apps import FsConfig
from .models import Files_Records

from .filesystem_daemon import get_entry

from config import CONFIG

# Create your views here.


class FsListView(generic.ListView):
    template_name = 'fs/entrylist.html'
    context_object_name = 'entries'

    def update_context(self, context, *args, **kwargs):
        return context

    def get(self, request, *args, **kwargs):

        kwargs.update(request.GET.dict())
        kwargs.update(request.POST.dict())

        self.object_list = self.get_queryset(*args, **kwargs)
        allow_empty = self.get_allow_empty()

        if not allow_empty:
            # When pagination is enabled and object_list is a queryset,
            # it's better to do a cheap query than to load the unpaginated
            # queryset in memory.
            if self.get_paginate_by(self.object_list) is not None and hasattr(self.object_list, 'exists'):
                is_empty = not self.object_list.exists()
            else:
                is_empty = not self.object_list
            if is_empty:
                raise Http404(_('Empty list and “%(class_name)s.allow_empty” is False.') % {
                    'class_name': self.__class__.__name__,
                })
        context = self.get_context_data()
        # 更新render的context
        context = self.update_context(context, args, **kwargs)
        return self.render_to_response(context)


class IndexView(FsListView):
    template_name = 'fs/entrylist.html'
    context_object_name = 'entries'

    def get_queryset(self, *args, **kwargs):

        res = []
        for path in CONFIG["directories"]:
            try:
                entry = get_entry({"directory": "", "name": path})
            except ValueError:
                pass
            else:
                entry['modified_time'] = time.strftime(
                    "%Y-%m-%d %H:%M:%S", time.localtime(entry['update_time']))
                res.append(entry)
        return res

    def update_context(self, context, *args, **kwargs):
        context["current_path"] = '根目录'
        context['is_index'] = True
        return super().update_context(context, *args, **kwargs)


class DirConentsView(FsListView):
    template_name = 'fs/entrylist.html'
    context_object_name = 'entries'

    def get_queryset(self, *args, **kwargs):
        root = kwargs['path']
        res = []
        try :
            for name in os.listdir(root):
                try:
                    entry = get_entry({"directory": root, "name": name})
                except ValueError:
                    pass
                else:
                    entry['modified_time'] = time.strftime(
                        "%Y-%m-%d %H:%M:%S", time.localtime(entry['update_time']))
                    res.append(entry)
        except:
            logging.error(f"list directory <{root}> error")
        return res

    def update_context(self, context, *args, **kwargs):
        context["current_path"] = kwargs['path']
        splits = os.path.split(kwargs['path'])
        context['upper_path'] = splits[0]
        if splits[1] == '':
            context["upper_index"] = True
        return super().update_context(context, *args, **kwargs)

class SearchView(FsListView):
    template_name = 'fs/searchentrylist.html'
    context_object_name = 'entries'

    def get_queryset(self, *args, **kwargs):
        search = kwargs["search"]
        res = Files_Records.objects.filter(Q(name__contains=search))
        return res

    def update_context(self, context, *args, **kwargs):
        context['search'] = kwargs["search"]
        return super().update_context(context, *args, **kwargs)


def download_by_path(request, path):
    if not os.path.exists(path):
        return HttpResponse("Sorry but Not Found the File")

    def file_iter(file_path):
        with open(file_path, "rb") as f:
            while True:
                c = f.read(FileResponse.block_size)
                if c:
                    yield c
                else:
                    break
            

    try:
        response = FileResponse(file_iter(path))
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="{0}"'.format(escape_uri_path(os.path.split(path)[-1]))
        return response
    except:
        return HttpResponse("Sorry but Not Found the File")

